<template>
  <div>
    <div v-if="formItems.length" class="form-box">
      <tp-form
        ref="form"
        v-bind="formOptions"
        :form-items="formItems"
        :is-search-form="true"
        :search-btn-position="searchBtnPosition"
        :search-button="searchButton"
        :default-form="defaultForm"
        :origin-data="formData"
        @search="search"
        @reset="reset"
        @form-change="formChange"
      >
        <template v-for="item in formSlots" v-slot:[item]="scope">
          <slot :name="item" v-bind="scope" />
        </template>
        <template #handle-area>
          <slot name="handle-area" />
        </template>
      </tp-form>
      <div class="form-after">
        <slot name="form-after" />
      </div>
    </div>
    <div class="table-box">
      <div class="table-before">
        <slot name="table-before" />
      </div>
      <tp-table
        ref="table"
        v-loading="loading"
        :data="tableData"
        :columns="columns"
        :show-index="showIndex"
        :current="currentPage"
        :page-size="pageSize"
        :null-cell-text="nullCellText"
        v-bind="$attrs"
        v-on="$listeners"
      >
        <template v-for="item in [...columnSlots, ...headerSlots]" v-slot:[item]="scope">
          <slot :name="item" v-bind="scope" />
        </template>
      </tp-table>
      <div class="table-after">
        <slot name="table-after" />
      </div>
      <div v-if="showPagination" class="pagination-box">
        <el-pagination
          ref="pagination"
          :total="total"
          :current-page="currentPage"
          :page-size="pageSize"
          v-bind="mergedPageConfig"
          @current-change="pageChange"
          @size-change="pageSizeChange"
        />
      </div>
    </div>
  </div>
</template>

<script>
import tpForm from './tp-form'
import tpTable from './tp-table'
export default {
  name: 'PfTable',
  components: {
    tpTable,
    tpForm
  },
  model: {
    prop: 'originData',
    event: 'change'
  },
  props: {
    searchButton: {
      type: String,
      default: 'primary'
    },
    data: {
      type: Array,
      default: () => []
    },
    nullCellText: {
      type: String,
      default: '-'
    },
    // 表格列
    columns: {
      required: true,
      type: Array,
      default: () => []
    },
    // 查询条件项
    formItems: {
      type: Array,
      default: () => []
    },
    // form配置
    formOptions: {
      type: Object,
      default: () => ({})
    },
    // 是否展示分页
    showPagination: {
      type: Boolean,
      default: true
    },
    // 分页配置
    pageConfig: {
      type: Object,
      default: () => ({})
    },
    // 是否初始化立即自动触发获取数据
    initGetData: {
      type: Boolean,
      default: true
    },
    // 是否自动展示loading
    autoLoading: {
      type: Boolean,
      default: true
    },
    // 初始化数据
    originData: {
      type: Object,
      default: () => ({})
    },
    showIndex: {
      type: Boolean,
      default: false
    },
    defaultForm: {
      type: Object,
      default: () => ({})
    },
    // 搜索按钮位置
    searchBtnPosition: {
      type: String,
      default: 'left'
    },
    // 是否开启url携带参数
    searchUrl: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      pageSize: 10,
      currentPage: 1,
      searchQuery: {},
      formData: {},
      loading: false,
      tableData: [], // 表格数据
      total: 10 // 总分页数
    }
  },
  computed: {
    formSlots() {
      const list = []
      this.formItems.forEach((item) => {
        if (item.slot) {
          list.push(item.slot)
        }
      })
      return list
    },
    columnSlots() {
      return this.columns.filter((c) => c.slot).map((c) => c.slot)
    },
    headerSlots() {
      return this.columns.filter((c) => c.headerSlot).map((c) => c.headerSlot)
    },
    mergedPageConfig() {
      return {
        layout: 'total, prev, pager, next, sizes, jumper',
        background: true,
        ...this.pageConfig
      }
    }
  },
  watch: {
    data: {
      deep: true,
      handler() {
        if (!this.initGetData) {
          this.tableData = this.data || []
        }
      }
    }
  },
  created() {
    this.formData = { ...this.originData }
    this.searchQuery = { ...this.formData }
    if (this.initGetData) {
      this.getTableData()
    } else {
      this.tableData = this.data
    }
  },

  methods: {
    getRef(_ref, prop) {
      if (_ref === 'pagination') {
        return this.$refs[_ref]
      } else if (_ref === 'table') {
        return this.$refs['table'].getRef()
      } else {
        return this.$refs['form'].getRef(_ref, prop)
      }
    },
    // 传入数据
    setTableData({ data, total }) {
      this.tableData = data || []
      this.total = total || 0
    },
    setSearchUrl(searchData) {
      this.$router.replace({
        query: {
          ...this.$route.query,
          searchObj: JSON.stringify(searchData)
        }
      })
    },
    // 获取动态数据
    getTableData() {
      if (this.autoLoading) {
        this.loading = true
      }
      const params = {
        ...this.searchQuery

      }
      if (this.showPagination) {
        const pageInfo = {
          pageNo: this.currentPage,
          pageSize: this.pageSize
        }
        Object.assign(params, pageInfo)
      }
      this.searchUrl && this.setSearchUrl(params)
      this.$emit('get-table-data', params, ({ data, total }) => {
        this.loading = false
        this.tableData = data || []
        this.total = total || 0
      })
    },
    setFormData(key, val) {
      this.$refs.form.setFormData(key, val)
    },
    search(formData) {
      this.searchQuery = { ...formData }
      this.currentPage = 1
      this.getTableData()
    },
    reset(form) {
      this.formData = { ...form }
      this.searchQuery = { ...form }
      this.currentPage = 1
      this.$emit('reset')
      this.getTableData()
    },
    formChange(val) {
      this.formData = { ...val }
      this.$emit('change', val)
    },
    pageChange(val) {
      this.currentPage = val
      this.getTableData()
    },
    pageSizeChange(val) {
      this.currentPage = 1
      this.pageSize = val
      this.getTableData()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep {
  .form-box {
    .el-select,
    .el-cascader,
    .el-date-editor {
      width: 100%;
    }
  }
}
.form-box {
  background-color: #fff;
  margin-bottom: 15px;
}
.table-box {
  background-color: #fff;
}

.pagination-box {
  width: 100%;
  text-align: right;
  margin: 15px 0 0 0;
}
.table-after, .form-after {
  margin-top: 15px;
}
.table-before{
  margin-bottom: 15px;
}

</style>
